EKS Auto Mode で Cilium をネットワークポリシーエンジンとして利用して、名前空間ごとに RDS アクセスを制限してみた

EKS Auto Mode で Cilium をネットワークポリシーエンジンとして利用して、名前空間ごとに RDS アクセスを制限してみた

EKS Auto Mode を使うことで、ノードの管理を AWS にオフロードできるなど、多くのメリットがあります。

https://dev.classmethod.jp/articles/eks-auto-mode/

一方、現時点での制約として Pod の Security Group が使えないという物があります(2025 年 1 月時点)。

EKS Auto Mode does not support:
Security Groups per Pod (SGPP).
https://docs.aws.amazon.com/eks/latest/userguide/auto-networking.html

Network Policy を利用した Kubernetes 内の通信制御は可能ですが、RDS など AWS リソースとの通信制御時には少しやり辛さがあるかもしれません。

https://dev.classmethod.jp/articles/eks-auto-mode-network-policy/

Network Policy でも IP ベースの通信制御は可能ですが、AWS リソースは IP が変更することを意識する必要があるケースが多いため、あまり使いやすい方法は言えません。
Pod のセキュリティグループを Network Policy と併用することで、Pod と AWS リソースの通信制御を行いやすくなります。ただし、Kubernetes 内の通信制御は Network Policy の方が扱いやすいので併用が推奨されます。

Network Policy and Security Groups for pod
By using a combination of security groups for pods and network policies, you can enhance your security posture. When network policy is enabled, security groups for pods serve as an additional layer in your defense-in-depth strategy. Network policies allow you to enforce granular controls over the flow of network traffic within your cluster whereas security groups for pods provides added protection by leveraging Amazon’s semantic controls to manage communications with resources within the Virtual Private Cloud (VPC), such as Amazon RDS databases. Amazon EKS strongly recommends employing network policies to restrict network communication between pods, thus reducing the attack surface and minimizing potential vulnerabilities. Please refer Amazon EKS Best Practices for complete guidance on using security groups alongside network policy.
https://aws.amazon.com/jp/blogs/containers/amazon-vpc-cni-now-supports-kubernetes-network-policies/

代替手段として DNS ベースで通信制御を行うことができる Cilium を利用することで、名前空間ごとに RDS への接続制御を行う方法を試してみました。
EKS Auto Mode は機能の一部として VPC CNI を提供しているため、今回はネットワークポリシーエンジンとしてのみ利用します。

With Amazon EKS Auto Mode, you don’t need to install or upgrade networking add-ons. Auto Mode includes pod networking and load balancing capabilities.
https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html

やってみる

v1.31 で Auto Mode を有効化した EKS を作成します。
作成手順は他記事で取り上げているので省略します。

マネジメントコンソールで作成したパターン。

https://dev.classmethod.jp/articles/eks-auto-mode/

eksctl で作成したパターン。

https://dev.classmethod.jp/articles/create-auto-mode-eks-cluster-with-eksctl/

Terraform で作成したパターン。

https://dev.classmethod.jp/articles/create-eks-auto-mode-cluster-by-terraform/

Cilium を AWS VPC CNI plugin と併用する手順に沿ってインストールします。

https://docs.cilium.io/en/v1.14/installation/cni-chaining-aws-cni/#chaining-aws-cni

リポジトリを追加します。

helm repo add cilium https://helm.cilium.io/

Cilium をインストールします。

helm install cilium cilium/cilium --version 1.14.18 \
  --namespace kube-system \
  --set cni.chainingMode=aws-cni \
  --set cni.exclusive=false \
  --set enableIPv4Masquerade=false \
  --set routingMode=native \
  --set endpointRoutes.enabled=true

無事、cilium-agent と cilium-operator が起動しました。

% kubectl get pod -n kube-system
NAME                              READY   STATUS    RESTARTS   AGE
cilium-9vkdn                      1/1     Running   0          3m59s
cilium-nhcks                      1/1     Running   0          3m58s
cilium-operator-9f7574fd9-424rz   1/1     Running   0          4m19s
cilium-operator-9f7574fd9-xmbkw   1/1     Running   0          4m19s

名前空間を 2 つ作って、それぞれに CiliumNetworkPolicy を作成します。

kubectl create ns app1
kubectl create ns app2

app1 用の CiliumNetworkPolicy です。
こちらでのみ、RDS への接続を許可します。
名前空間内での通信や、名前解決用の通信は許可しておきます。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: app1-network-policy
  namespace: app1
spec:
  endpointSelector:
    matchLabels: {}
  ingress:
    - fromEndpoints:
        - matchLabels: {}
  egress:
    - toEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": app1
    - toFQDNs:
        - matchPattern: "sample-aurora-postgres-cluster.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com"
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP
    - toPorts:
        - ports:
            - port: "53"
              protocol: ANY
          rules:
            dns:
              - matchPattern: "*"

app2 用の CiliumNetworkPolicy です。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: app2-network-policy
  namespace: app2
spec:
  endpointSelector:
    matchLabels: {}
  ingress:
    - fromEndpoints:
        - matchLabels: {}
  egress:
    - toEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": app2
    - toPorts:
        - ports:
            - port: "53"
              protocol: ANY
          rules:
            dns:
              - matchPattern: "*"

app1 と app2 に Pod を作成して DB にアクセスさせてみます。
下記構成になります。

Untitled(29).png

postgres コンテナを名前空間 app1 に起動して接続します。

% kubectl run postgres -it --rm --image=postgres:latest -n app1 /bin/bash

コンテナ内から、無事 RDS に接続できました。

root@postgres:/# psql -h $DB_HOST -U postgres
Password for user postgres:
psql (17.2 (Debian 17.2-1.pgdg120+1), server 16.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: none)
Type "help" for help.
postgres=>

app2 側にもコンテナを作成します。

% kubectl run postgres -it --rm --image=postgres:latest -n app2 /bin/bash

こちらから接続を試行した場合はタイムアウトになりました。

root@postgres:/# psql -h $DB_HOST -U postgres
psql: error: connection to server at "sample-aurora-postgres-cluster.cluster-xxxxxxx.ap-northeast-1.rds.amazonaws.com" (10.0.102.183), port 5432 failed: Connection timed out
        Is the server running on that host and accepting TCP/IP connections?

無事通信を制御できていますね!

まとめ

EKS Auto Mode で Cilium を利用して、RDS との接続を制御してみました。
今後 EKS Auto Mode でも Pod のセキュリティグループを使えるようになる可能性はありますが、それまでは AWS リソースとの通信制御に有用ではないでしょうか!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.